﻿using Examination.Args;
using Examination.Args.Request;
using Examination.Filter;
using Examination.Model;
using Examination.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Examination.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [TypeFilter(typeof(WebVerificationSysAdminFilterAttribute))]
    public class UserController : ControllerBase
    {
        private readonly DataContext _dataContext;

        public UserController(DataContext dataContext) => _dataContext = dataContext;

        [HttpPost]
        public async Task<IActionResult> Search([FromBody] ListParameter parameter)
        {
            if (string.IsNullOrEmpty(parameter.Key))
            {
                var users = await _dataContext.Users.Select(u => new { u.Id, u.CreateTime, u.Name, u.Number, u.Class, u.Type }).OrderByDescending(u => u.CreateTime).Skip(parameter.Page * parameter.Size).Take(parameter.Size).ToListAsync();
                long total = await _dataContext.Users.CountAsync();
                long all = await _dataContext.Users.CountAsync();
                long general = await _dataContext.Users.CountAsync(u => u.Type == UserType.General);
                long admin = await _dataContext.Users.CountAsync(u => u.Type == UserType.Admin);
                long system = await _dataContext.Users.CountAsync(u => u.Type == UserType.System);
                return new JsonResult(new ResponseData() { Data = new { all, users, general, admin, system, total } });
            }
            else
            {
                var users = await _dataContext.Users.Select(u => new { u.Id, u.CreateTime, u.Name, u.Number, u.Class, u.Type, t = u.Type == UserType.General ? "普通用户" : (u.Type == UserType.Admin ? "管理员" : "系统管理员") }).Where(u => u.Name.Contains(parameter.Key) || u.Number.Contains(parameter.Key) || u.Class.Contains(parameter.Key) || u.t.Contains(parameter.Key)).OrderByDescending(u => u.CreateTime).Skip(parameter.Page * parameter.Size).Take(parameter.Size).ToListAsync();
                long total = await _dataContext.Users.Select(u => new { u.Id, u.CreateTime, u.Name, u.Number, u.Class, u.Type, t = u.Type == UserType.General ? "普通用户" : (u.Type == UserType.Admin ? "管理员" : "系统管理员") }).CountAsync(u => u.Name.Contains(parameter.Key) || u.Number.Contains(parameter.Key) || u.Class.Contains(parameter.Key) || u.t.Contains(parameter.Key));
                long all = await _dataContext.Users.CountAsync();
                long general = await _dataContext.Users.CountAsync(u => u.Type == UserType.General);
                long admin = await _dataContext.Users.CountAsync(u => u.Type == UserType.Admin);
                long system = await _dataContext.Users.CountAsync(u => u.Type == UserType.System);
                return new JsonResult(new ResponseData() { Data = new { all, users, general, admin, system, total } });
            }
        }

        [HttpPost]
        public async Task<IActionResult> Add([FromBody] AddUserParameter parameter)
        {
            if (await _dataContext.Users.CountAsync(u => u.Number.Equals(parameter.Number)) > 0)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "添加失败，已存在该学号的用户" });
            }
            User user = new User()
            {
                Name = parameter.Name,
                Number = parameter.Number,
                Class = parameter.Class,
                Type = parameter.Type,
                Password = MD5Helper.GenerateMD5(MD5Helper.GenerateMD5(parameter.Number.Substring(6)))
        };
            await _dataContext.Users.AddAsync(user);
            await _dataContext.SaveChangesAsync();
            return new JsonResult(new ResponseData());
        }

        [HttpPost]
        public async Task<IActionResult> Update([FromBody] UpdateUserParameter parameter, [FromServices] IArgsExtend argsExtend)
        {
            User self = ((ArgsExtend)argsExtend).User;
            User user = await _dataContext.Users.FirstOrDefaultAsync(u => u.Id == parameter.Id);
            if (user == null)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "修改失败，该用户不存在" });
            }
            if (self.Id == user.Id && self.Type != parameter.Type)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "修改失败，不允许修改自己的类型" });
            }
            user.Name = parameter.Name;
            user.Number = parameter.Number;
            user.Class = parameter.Class;
            user.Type = parameter.Type;
            _dataContext.Users.Update(user);
            await _dataContext.SaveChangesAsync();
            return new JsonResult(new ResponseData());
        }

        [HttpPost]
        public async Task<IActionResult> Delete([FromQuery] int id, [FromServices] IArgsExtend argsExtend)
        {
            User self = ((ArgsExtend)argsExtend).User;
            if (self.Id == id)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "删除失败，不允许删除自己" });
            }
            User user = await _dataContext.Users.FirstOrDefaultAsync(u => u.Id == id);
            if (user == null)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "删除失败，该用户不存在" });
            }
            if (await _dataContext.Examinations.CountAsync(e => e.CreatorId == id) > 0)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "删除失败，存在该用户创建的比赛，你可以尝试先删除或修改比赛" });
            }
            long[] ids = _dataContext.Papers.Where(p => p.UserId == id).Select(p => p.Id).ToArray();
            _dataContext.PaperQuestions.RemoveRange(await _dataContext.PaperQuestions.Where(pq => ids.Contains(pq.PaperId)).ToListAsync());
            _dataContext.Papers.RemoveRange(await _dataContext.Papers.Where(p => p.UserId == id).ToListAsync());
            _dataContext.Users.Remove(user);
            await _dataContext.SaveChangesAsync();
            return new JsonResult(new ResponseData());
        }

        [HttpPost]
        public async Task<IActionResult> Reset([FromQuery] int id)
        {
            User user = await _dataContext.Users.FirstOrDefaultAsync(u => u.Id == id);
            if (user == null)
            {
                return new JsonResult(new ResponseData() { Status = 1, Msg = "重置失败，该用户不存在" });
            }
            user.Password = MD5Helper.GenerateMD5(MD5Helper.GenerateMD5(user.Number.Substring(6)));
            _dataContext.Users.Update(user);
            await _dataContext.SaveChangesAsync();
            return new JsonResult(new ResponseData());
        }
    }
}
